package population.populationFindPredicates;

import java.util.ArrayList;
import character.Character;

/**
 * Find character with specific social link.
 * @author pcdejager
 *
 */
public class FindSocialLink implements PopulationFindPredicate {
    /**
     * Links to check.
     * @author pcdejager
     *
     */
    public enum Link {
        /**
         * Love interest.
         */
        LOVEINTEREST,
        /**
         * Married.
         */
        MARRIED
    }

    /**
     * Condition to check.
     * @author pcdejager
     *
     */
    public enum Condition {
        /**
         * Link exist.
         */
        EXIST,
        /**
         * Link does not exist.
         */
        DOESNOTEXIST
    }

    /**
     * Default constructor.
     */
    public FindSocialLink() {
        conditions = new ArrayList<PopulationFindPredicate>();
    }

    /**
     * Constructor for special condition.
     * @param link The link
     * @param condition The condition
     */
    public FindSocialLink(final Link link, final Condition condition) {
        conditions = new ArrayList<PopulationFindPredicate>();
        addCondition(link, condition);
    }

    /**
     * Add a condition to check.
     * @param link The link
     * @param condition The condition
     */
    public final void addCondition(final Link link, final Condition condition) {
        switch (link) {
        case LOVEINTEREST:
            if (condition == Condition.EXIST) {
                conditions.add(new CheckHasLoveInterest());
            } else {
                conditions.add(new CheckNoLoveInterest());
            }
            break;
        case MARRIED:
            if (condition == Condition.EXIST) {
                conditions.add(new CheckMarried());
            } else {
                conditions.add(new CheckNotMarried());
            }
            break;
        default:
        }
    }

    /**
     * Check the character against condition.
     * @param c Character to test
     * @return True if found, else false
     */
    public final boolean check(final Character c) {
        boolean ok = true;
        for (PopulationFindPredicate p : conditions) {
            ok &= p.check(c);
        }
        return ok;
    }

    /**
     * Check if love interest exist.
     * @author pcdejager
     *
     */
    private class CheckHasLoveInterest implements PopulationFindPredicate {
        /**
         * Check method.
         * @param c The character to check
         * @return True if has love interest, else false.
         */
        public final boolean check(final Character c) {
            if (c.getSocialLinks().getLoveInterest() != null) {
                return true;
            }
            return false;
        }
    }

    /**
     * Check if love interest not exist.
     * @author pcdejager
     *
     */
    private class CheckNoLoveInterest implements PopulationFindPredicate {
        /**
         * Check method.
         * @param c The character to check
         * @return True if has no love interest, else false.
         */
        public final boolean check(final Character c) {
            if (c.getSocialLinks().getLoveInterest() == null) {
                return true;
            }
            return false;
        }
    }

    /**
     * Check if married.
     * @author pcdejager
     *
     */
    private class CheckMarried implements PopulationFindPredicate {
        /**
         * Check method.
         * @param c The character to check
         * @return True if married, else false.
         */
        public final boolean check(final Character c) {
            if (c.getSocialLinks().getSpouse() != null) {
                return true;
            }
            return false;
        }
    }

    /**
     * Check if not married.
     * @author pcdejager
     *
     */
    private class CheckNotMarried implements PopulationFindPredicate {
        /**
         * Check method.
         * @param c The character to check
         * @return True if not married, else false.
         */
        public final boolean check(final Character c) {
            if (c.getSocialLinks().getSpouse() == null) {
                return true;
            }
            return false;
        }
    }

    /**
     * Conditions to be checked.
     */
    private ArrayList<PopulationFindPredicate> conditions = null;
}
